package mybitcoin

import (
	"math/big"
	"bytes"
	"crypto/sha256"
	"fmt"
)

/**
工作量证明：对区块数据做哈希运算，寻找一个满足条件的随机数。小于目标难度值的随机数
 */

type ProofOfWork struct {
	//区块数据,不需要操作区块，所以不传递指针类型
	block Block
	//目标值
	target *big.Int
}

func NewProofOfWork(block Block) *ProofOfWork {
	pow := ProofOfWork{
		block: block,
	}
	//暂定困难值
	target := "0000100000000000000000000000000000000000000000000000000000000000" //TODO
	//bigint转换
	tmp := big.Int{}
	tmp.SetString(target, 16)
	pow.target = &tmp

	return &pow

}

func (pow *ProofOfWork) run() ([]byte, uint64) {
	//拼装区块数据得到hash
	block := pow.block

	//计算nonce值

	var nonce uint64
	var hash [32]byte

	for {
		tmp := [][]byte{
			block.PrevHash,
			block.Data,
			block.MerkleRoot,
			Uint64ToByte(block.Version),
			Uint64ToByte(block.TimeStamp),
			Uint64ToByte(block.Difficulty),
			Uint64ToByte(nonce)}

		blockInfo := bytes.Join(tmp, []byte(""))//拼接后的字节数组
		hash = sha256.Sum256(blockInfo)

		//与target比较，bigint转换【】byte
		tmpInt := big.Int{}

		tmpInt.SetBytes(hash[:])
		//与困难值比较
		if tmpInt.Cmp(pow.target)==-1{
			//挖矿成功，返回数据
			fmt.Printf("挖矿成功，hash:=%x,nonce:=%d\n",hash[:],nonce)
			return hash[:],nonce

		}else{
			//没有找到
			nonce++
		}


	}

}
